﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.Threading;
using IntelligentFiles.HcCommon;
namespace Common
{
    /// <summary>
    /// 公共方法工具类
    /// jsx 2019-10-16
    /// </summary>
    class CommonApi
    {      
        #region《日志处理》
        /// <summary>
        /// windows 异常类
        /// </summary>
        static EventLog errLog = new EventLog();
        static Thread _ThreMsg;
        static Queue<string> MSGQueue = new Queue<string>();
        /// <summary>
        /// 记录日志文件 添加至日志队列
        /// </summary>
        /// <param name="messageLog"></param>
        public static void writeLog(string messageLog)
        {
            if (messageLog.Length>0)
            {
                MSGQueue.Enqueue(messageLog);
            }
        }
        /// <summary>
        /// 初始化 日志线程
        /// 消息日志记录由主线程直接写入文件改为由独立的日志线程操作 调用方式不变 通过消息队列接受和处理消息日志
        /// 由UDP日志分发服务时不会造成主线程卡顿
        /// 2019-12-4 jsx
        /// </summary>
        public static void initLogThread()
        {
            try
            {
                _ThreMsg = new Thread(new ThreadStart(LogThread));
                _ThreMsg.IsBackground = true;
                _ThreMsg.Start();
            }
            catch (Exception ex)
            {
                Log("初始化日志错误,"+ex.ToString());
            }
        }
        private static void LogThread()
        {
            while (true)
            {
                //刷新消息
                if (MSGQueue.Count > 0)
                {
                    Log(MSGQueue.Dequeue());
                }
                Thread.Sleep(10);
            }
        }
        /// <summary>
        /// 日志处理
        /// </summary>
        /// <param name="msg"></param>
        private static void Log(string msg)
        {
            try
            {
                if (!Directory.Exists(Application.StartupPath + "/MessageLog"))
                {
                    Directory.CreateDirectory(Application.StartupPath + "/MessageLog");
                }
                //将日志写入文件
                StreamWriter sw = new StreamWriter(Application.StartupPath + "/MessageLog" + "/" + DateTime.Now.ToString("yyyy-MM-dd") + "—log.txt", true);
                string logmsg = "Log#" + DateTime.Now.ToString("") + "===" + msg + "\r\n";
                sw.Write(logmsg);
                sw.Close();
            }
            catch (Exception ex)
            {
                errLog.WriteEntry("写消息日志方法异常，原因:" + ex.Message);//日志出现异常，记录到windows系统日志
            }
        }
        #endregion

        #region 《配置读取》

        /// <summary>
        /// 读取系统配置文件
        /// </summary>
        public static void readConfig()
        {
            try
            {
                string Config_File = Application.StartupPath + "/Config/ExamSubject.ini";
                if (File.Exists(Config_File))
                {
                    INIClass iniClass = new INIClass(Config_File);

                    ComParam.address = iniClass.IniReadValueDefault("System", "address", "");
                    ComParam.rfidCom = iniClass.IniReadValueDefault("COM", "rfidCom", "");
                    ComParam.codeCom = iniClass.IniReadValueDefault("COM", "codeCom", "");
                    ComParam.lockCom = iniClass.IniReadValueDefault("COM", "lockCom", "");

                }
                else
                {
                    writeLog("读取系统配置文件异常！");
                }
            }
            catch (Exception ex)
            {
                writeLog("读取系统配置文件异常," + ex.ToString());
            }
        }
        #endregion

        #region《通用方法》
        /// <summary>
        /// 16进制字符串转10进制数字
        /// </summary>
        /// <param name="strHex"></param>
        /// <returns></returns>
        public static int getHex(string strHex)
        {
            int hex = 0;
            hex = int.Parse(strHex, System.Globalization.NumberStyles.HexNumber);
            return hex;
        }

        public static long ConvertDateTimeToInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位      
            return t;
        }
        /// <summary>
        /// 标记当前时间戳
        /// </summary>
        /// <returns></returns>
        public static long GetMS_Cur()
        {
            long lTime = ConvertDateTimeToInt(DateTime.Now);
            return lTime;
        }
        /// <summary>
        /// 获取从标记开始到现在用了多久
        /// </summary>
        /// <param name="lStartTime">开始时间</param>
        /// <returns></returns>
        public static long GetMS_Sub(long lStartTime)
        {
            long lTime = ConvertDateTimeToInt(DateTime.Now) - lStartTime;
            return lTime;
        }

        /// <summary>
        /// 根据字符串获取字段并赋值
        /// </summary>
        /// <param name="obj">需要赋值的obj</param>
        /// <param name="fieldname">字符串名称</param>
        /// <param name="value">需要赋的值</param>
        public static void SetObjectValue(object obj, string fieldName, object value)
        {
            //默认获取公共
            FieldInfo info = obj.GetType().GetField(fieldName);
            if (null != info)
            {
                obj.GetType().GetField(fieldName).SetValue(obj, value);
            }
        }
        /// <summary>
        /// 根据字符串获取属性并赋值
        /// 用于封装的属性
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public static void SetPropertyValue(object obj, string propertyName, object value)
        {
            //默认获取公共
            PropertyInfo info = obj.GetType().GetProperty(propertyName);
            if (null != info)
            {
                obj.GetType().GetProperty(propertyName).SetValue(obj, value);
            }
        }
        /// <summary>
        /// 16进制字符串转化为8位2进制数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static string HexString2BinString(string hexString)
        {
            string result = string.Empty;
            foreach (char c in hexString)
            {
                int v = Convert.ToInt32(c.ToString(), 16);
                int v2 = int.Parse(Convert.ToString(v, 2));
                result += string.Format("{0:d4}", v2);
            }
            return result;
        }
        /// <summary>
        /// 获取随机数集合
        /// jsx 2019-12-10
        /// </summary>
        /// <param name="istart">随机数可取该下界值</param>
        /// <param name="iend">随机数不能取该上界值</param>
        /// <param name="number">返回随机数的数量</param>
        /// <param name="endFlag">结尾标志 此数若出现在集合中 必须在结尾处 值为0时 不做特殊处理</param>
        /// <returns></returns>
        public static int[] getRandoms(int istart, int iend, int number, int endFlag)
        {
            int[] results = new int[number];
            int i = 0, result = 0;
            Random randObj = new Random();
            bool state = false;
            while (i < number)
            {
                state = true;
                result = randObj.Next(istart, iend);
                if (endFlag!=0)
                {
                    if (result == endFlag && i < (number - 1))
                    {
                        state = false;
                        continue;
                    }
                }
                for (int j = 0; j < number; j++)
                {
                    if (result == results[j])
                    {
                        state = false;
                        break;
                    }
                }

                if (state)
                {
                    results[i] = result;
                    i++;
                }
            }
            return results;
        }
        /// <summary>
        /// 获取随机数
        /// </summary>
        /// <param name="min">随机数可取该下界值</param>
        /// <param name="max">随机数不能取该上界值</param>
        /// <returns></returns>
        public static int getRandom(int min, int max)
        {
            int result=0;
            Random randObj = new Random();
            result = randObj.Next(min, max);
            return result;
        }
        #endregion
    }
}
